function Shake(options = {}) {
  //feature detect

  const defaultOptions = {
    threshold: 15, //default velocity threshold for shake to register
    timeout: 1000 //default interval between events
  };
  this.options = Object.assign({}, defaultOptions, options);

  //use date to prevent multiple shakes firing
  this.lastTime = new Date();

  //accelerometer values
  this.lastX = null;
  this.lastY = null;
  this.lastZ = null;
}

//reset timer values
Shake.prototype.reset = function() {
  this.lastTime = new Date();
  this.lastX = null;
  this.lastY = null;
  this.lastZ = null;
};

//start listening for devicemotion
Shake.prototype.start = function() {
  this.reset();
};

//stop listening for devicemotion
Shake.prototype.stop = function() {
  // if (this.hasDeviceMotion) {
  //     window.removeEventListener('devicemotion', this, false);
  // }
  this.reset();
};

//calculates if shake did occur
Shake.prototype.devicemotion = function(e) {
  var current = e.accelerationIncludingGravity;
  var currentTime;
  var timeDifference;
  var deltaX = 0;
  var deltaY = 0;
  var deltaZ = 0;

  if (this.lastX === null && this.lastY === null && this.lastZ === null) {
    this.lastX = current.x;
    this.lastY = current.y;
    this.lastZ = current.z;
    return;
  }

  deltaX = Math.abs(this.lastX - current.x);
  deltaY = Math.abs(this.lastY - current.y);
  deltaZ = Math.abs(this.lastZ - current.z);

  if (
    (deltaX > this.options.threshold && deltaY > this.options.threshold) ||
    (deltaX > this.options.threshold && deltaZ > this.options.threshold) ||
    (deltaY > this.options.threshold && deltaZ > this.options.threshold)
  ) {
    //calculate time in milliseconds since last shake registered
    currentTime = new Date();
    timeDifference = currentTime.getTime() - this.lastTime.getTime();

    if (timeDifference > this.options.timeout) {
      // dispatch
      this.options.onChange && this.options.onChange();
      this.lastTime = new Date();
    }
  }

  this.lastX = current.x;
  this.lastY = current.y;
  this.lastZ = current.z;
};

//event handler
Shake.prototype.handleEvent = function(e) {
  if (typeof this[e.type] === "function") {
    return this[e.type](e);
  }
};

export { Shake };
